// 前端 同时多次调用同个接口，只触发一次而不是触发多次

// 场景：
// 我们进入某应用项目某页面，同时调用多个接口，此时，我们需要请求token，如果我们使用的是axios来请求，我们一般会在请求拦截器里进行处理，大致是如何检查到本地缓存不存在 token，说明是第一次进入应用，还没请求token并缓存下到本地，与此同时调用多个接口，也就会触发请求token的接口多次，而我们理想的方案是多个接口使用的是均是第一次请求的token，后续接口使用的也是第一次缓存的token，那么我们如何操作才能达实现呢？

{
  // 一个 重复触发多次，只返回第一次请求的结果 函数
  function repeatOnce(getResult, local_name) {
    return new Promise(async (resolve) => {
      const local_result = localStorage.getItem(local_name);
      if (local_result) {
        console.log('存在');
        resolve(local_result);
      } else {
        if (!repeatOnce.count) {
          repeatOnce.count = 0;
          repeatOnce.count++;
          console.log('刚进入应用页面，缓存结果不存在，需要请求并缓存到本地');
          const request_result = await getResult();
          localStorage.setItem(local_name, request_result);
          resolve(request_result);
          repeatOnce.emitter.emit('ok', request_result);
        } else {
          repeatOnce.count++;
          console.log('第' + repeatOnce.count + '次请求等待返回结果');
          repeatOnce.emitter.on('ok', (result) => {
            repeatOnce.count = 0;
            resolve(result);
          });
        }
      }
    });
  }

  repeatOnce.emitter = {
    _events: {},
    on(eventName, callback) {
      if (!this._events[eventName]) {
        this._events[eventName] = [callback];
      } else {
        this._events[eventName].push(callback);
      }
    },
    emit(eventName, ...args) {
      this._events[eventName]?.forEach((fn) => fn(...args));
    },
  };

  // 模拟的请求token的方法
  function getToken() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('我是请求的结果数据 - token');
      }, 1000);
    });
  }

  // token Promise
  const token = repeatOnce.bind(null, getToken, 'Access_Token');

  // 页面有3个方法，每个方法里面都调用了同个接口，类似token
  async function request1() {
    const res = await token();
    console.log('request1', res);
  }
  async function request2() {
    const res = await token();
    console.log('request2', res);
  }
  async function request3() {
    const res = await token();
    console.log('request3', res);
  }

  request1();
  request2();
  request3();
}
